package shop.core.common.oscache;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import shop.core.common.bean.FrontContainer;
import shop.core.util.DateTimeUtil;
import shop.core.util.KeyValueHelper;
import shop.services.front.area.AreaService;
import shop.services.front.area.bean.Area;
import shop.services.front.catalog.CatalogService;
import shop.services.front.catalog.bean.Catalog;
import shop.services.front.express.ExpressService;
import shop.services.front.express.bean.Express;
import shop.services.front.indexImg.IndexImgService;
import shop.services.front.indexImg.bean.IndexImg;
import shop.services.front.keyvalue.KeyvalueService;
import shop.services.front.keyvalue.bean.Keyvalue;
import shop.services.front.news.NewsService;
import shop.services.front.news.bean.News;
import shop.services.front.product.ProductService;
import shop.services.front.product.bean.Product;
import shop.services.front.product.bean.ProductStockInfo;
import shop.services.manage.accountRank.AccountRankService;
import shop.services.manage.accountRank.bean.AccountRank;
import shop.services.manage.activity.ActivityService;
import shop.services.manage.activity.bean.Activity;

import java.util.*;
import java.util.Map.Entry;

/**
 * 缓存管理器。 后台项目可以通过接口程序通知该类重新加载部分或全部的缓存
 *
 * @author huangf
 */
public class FrontCache {
    private static final Logger logger = LoggerFactory.getLogger(FrontCache.class);

    @Autowired
    private KeyvalueService keyvalueService;
    @Autowired
    private CatalogService catalogService;
    @Autowired
    private IndexImgService indexImgService;
    @Autowired
    private AreaService areaService;
    @Autowired
    private ExpressService expressService;
    @Autowired
    private AccountRankService accountRankService;
    @Autowired
    private ProductService productService;

    private static SystemManager systemManager;

    @Autowired
    public void setSystemManager(SystemManager systemManager) {
        FrontCache.systemManager = systemManager;
    }



    /**
     * 加载key-value键值对
     */
    public void loadKeyValue() {
        logger.info("load...");
        KeyValueHelper.load(keyvalueService.selectList(new Keyvalue()));
    }




    /**
     * 如果类别ID是主类别，则返回该主类别的下面所有子类别
     *
     * @param catalogID
     * @return
     */
    public static List<Catalog> loadCatalogChildren(String catalogID) {
        try {
            logger.info(">>catalogID=" + catalogID);
            if (StringUtils.isBlank(catalogID)) {
                throw new NullPointerException();
            }
            Catalog catalog = systemManager.getCatalogsMap().get(catalogID);
            if (catalog == null) {
                throw new NullPointerException();
            }

            if (catalog.getPid().equals("0")) {
                if (catalog.getChildren() == null) {
                    logger.info(">>主类别catalog.getChildren()=0");
                } else {
                    logger.info(">>主类别catalog.getChildren()=" + catalog.getChildren().size());
                }
                //主类别
                return catalog.getChildren();
            } else {
                //子类别

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getPid(String catalogID) {
        if (StringUtils.isBlank(catalogID)) {
            throw new NullPointerException();
        }
        Map<String, Catalog> catalogsMap = systemManager.getCatalogsMap();
        Catalog catalog = catalogsMap.get(catalogID);
        if (catalog == null) {
            throw new NullPointerException();
        }
        if (catalog.getPid().equals("0")) {
            return catalog.getId();
        } else {
            catalog = catalogsMap.get(catalog.getPid());
            return catalog.getId();
        }
    }

    /**
     * 加载目录列表,树形结构
     *
     * @param loadProduct 是否加载商品数据。true：加载，false:不加载
     * @throws Exception
     */
    public void loadCatalogs(boolean loadProduct) throws Exception {
        logger.info("load...");

        List<Catalog> catalogs = loadCatalogs2("p");
        systemManager.setCatalogs(catalogs);
        List<Catalog> catalogsArticle = loadCatalogs2("a");
        systemManager.setCatalogsArticle(catalogsArticle);
        Map<String, Catalog> catalogsMap = Maps.newHashMap();
        Map<String, Catalog> catalogsCodeMap = Maps.newHashMap();
        putToMap(systemManager.getCatalogs(), loadProduct, catalogsMap, catalogsCodeMap);
        systemManager.setCatalogsMap(catalogsMap);
        systemManager.setCatalogsCodeMap(catalogsCodeMap);
    }

    /**
     * 将商品目录结构转化为map的形式。
     *
     * @param catalogs
     * @throws Exception
     */
    public void putToMap(List<Catalog> catalogs, boolean loadProduct, Map<String, Catalog> catalogsMap, Map<String, Catalog> catalogsCodeMap) throws Exception {
        if (catalogs == null || catalogs.size() == 0) {
            return;
        }
        for (int i = 0; i < catalogs.size(); i++) {
            Catalog item = catalogs.get(i);

            catalogsMap.put(item.getId(), item);

            if (catalogsCodeMap.get(item.getCode()) != null) {
                logger.error("item.code = " + item.getCode());
                throw new Exception("错误：商品类别code重复!");
            }

            catalogsCodeMap.put(item.getCode(), item);
            if (item.getChildren() != null && item.getChildren().size() > 0) {
                //递归调用
                putToMap(item.getChildren(), loadProduct, catalogsMap, catalogsCodeMap);
            }
        }
    }


    /**
     * 原来递归的方式修改为非递归方式。
     * 非递归方法查询商品，并且自动排序。
     * @param type
     */
    private List<Catalog> loadCatalogs2(String type) {
        List<Catalog> catalogs = Lists.newLinkedList();
        Catalog cc = new Catalog();
        cc.setType(type);
        List<Catalog> catalogsList = catalogService.selectList(cc);
        if (catalogsList != null) {

            Map<String, Catalog> map = new HashMap<String, Catalog>();
            for (Iterator<Catalog> it = catalogsList.iterator(); it.hasNext(); ) {
                Catalog item = it.next();

                if (StringUtils.isNotBlank(item.getPid()) && item.getPid().equals("0")) {
                    //是否在导航栏显示中文化
                    if (item.getShowInNav().equals(Catalog.catalog_showInNav_y)) {
                        item.setShowInNavStr("是");
                    }

                    map.put(item.getId(), item);
                    it.remove();
                }
            }

            for (Iterator<Catalog> it = catalogsList.iterator(); it.hasNext(); ) {
                Catalog item = it.next();
                if (StringUtils.isNotBlank(item.getPid())) {
                    Catalog rootItem = map.get(item.getPid());
                    if (rootItem != null) {
                        if (rootItem.getChildren() == null) {
                            rootItem.setChildren(new LinkedList<Catalog>());
                        }
                        rootItem.getChildren().add(item);
                    }
                    it.remove();
                }
            }

            for (Iterator<Entry<String, Catalog>> it = map.entrySet().iterator(); it.hasNext(); ) {
                catalogs.add(it.next().getValue());
            }

            //对主类别和子类别进行排序
            Collections.sort(catalogs, new Comparator<Catalog>() {
                public int compare(Catalog o1, Catalog o2) {
                    if (o1.getOrder1() > o2.getOrder1()) {
                        return 1;
                    } else if (o1.getOrder1() < o2.getOrder1()) {
                        return -1;
                    }
                    return 0;
                }
            });

            for (int i = 0; i < catalogs.size(); i++) {
                if (catalogs.get(i).getChildren() == null) {
                    continue;
                }
                Collections.sort(catalogs.get(i).getChildren(), new Comparator<Catalog>() {
                    public int compare(Catalog o1, Catalog o2) {
                        if (o1.getOrder1() > o2.getOrder1()) {
                            return 1;
                        } else if (o1.getOrder1() < o2.getOrder1()) {
                            return -1;
                        }
                        return 0;
                    }
                });
            }
        }
        return catalogs;
    }

    /**
     * 加载门户滚动图片列表
     */
    public void loadIndexImgs() {
        logger.info("loadIndexImgs...");
        IndexImg c = new IndexImg();
        List<IndexImg> indexImages = indexImgService.selectList(c);
        systemManager.setIndexImages(indexImages);
    }



    /**
     * 加载商品内存库存
     */
    public void loadProductStock() {
        List<ProductStockInfo> list = productService.selectStockList(new Product());
        Map<String, ProductStockInfo> productStockMap = Maps.newHashMap();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                ProductStockInfo p = list.get(i);
                productStockMap.put(p.getId(), p);
            }
        }
        systemManager.setProductStockMap(productStockMap);
    }


    /**
     * 加载物流列表
     */
    private void loadExpress() {
        List<Express> expressList = expressService.selectList(new Express());
        Map<String, Express> expressMap = Maps.newHashMap();
        if (expressList != null && expressList.size() > 0) {
            for (int i = 0; i < expressList.size(); i++) {
                Express item = expressList.get(i);
                expressMap.put(item.getCode(), item);
            }
        }
        systemManager.setExpressMap(expressMap);
    }


    /**
     * 加载省市区数据
     */
    public void loadArea() {
        logger.error("loadArea...");
        Area area = new Area();
        List<Area> areas = areaService.selectList(area);
        List<Area> rootAreas = Lists.newArrayList();
        for (Area a : areas) {
            if ("0".equals(a.getPcode())) {
                rootAreas.add(a);
            }
        }
        if (rootAreas.size() == 0) {
            return;
        }

        for (Area a : rootAreas) {
            getAreaByDigui(a, areas);
        }

        Map<String, Area> map = new TreeMap<String, Area>();
        for (Area a : rootAreas) {
            map.put(a.getCode(), a);
        }
        systemManager.setAreaMap(map);
    }


    /**
     * 递归加载省份下的：城市、区域、以后还会有街道的数据
     *
     * @param item
     * @param areas 所有的地区列表
     */
    private void getAreaByDigui(Area item, final List<Area> areas) {
        List<Area> children = Lists.newArrayList();
        for (Area a : areas) {
            if (item.getCode().equals(a.getPcode())) {
                children.add(a);
            }
        }

        item.setChildren(children);
        if (children.size() == 0) {
            return;
        }

        for (Area a : children) {
            getAreaByDigui(a, areas);
        }
    }




    /**
     * 加载会员等级列表
     */
    private void loadAccountRank() {
        List<AccountRank> list = accountRankService.selectList(new AccountRank());
        Map<String, AccountRank> accountRankMap = Maps.newHashMap();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                AccountRank item = list.get(i);
                accountRankMap.put(item.getCode(), item);
            }
        }
        systemManager.setAccountRankMap(accountRankMap);
    }



    /**
     * 加载全部的缓存数据
     *
     * @throws Exception
     */
    public void loadAllCache() throws Exception {
        logger.info("loadAllCache...");
        loadCatalogs(true);
        loadIndexImgs();
        loadKeyValue();
        loadArea();
        loadExpress();
        loadProductStock();
        loadAccountRank();
        logger.info("前台缓存加载完毕!");
    }
}
